﻿using Microsoft.Extensions.Caching.Memory;
using System;

namespace WxTenpay.Common
{
    public class CacheHelper
    {
      
            protected IMemoryCache _cache;

            public CacheHelper(IMemoryCache cache)
            {
                _cache = cache;
            }

            public static CacheHelper Default { get; private set; }
            static CacheHelper()
            {
                Default = new CacheHelper(new MemoryCache(new MemoryCacheOptions()));
            }

            /// <summary>
            /// 是否存在此缓存
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public bool Exists(string key)
            {
                if (string.IsNullOrWhiteSpace(key))
                    throw new ArgumentNullException(nameof(key));
                object v = null;
                return _cache.TryGetValue<object>(key, out v);
            }

            /// <summary>
                    /// 取得缓存数据
                    /// </summary>
                    /// <typeparam name="T"></typeparam>
                    /// <param name="key"></param>
                    /// <returns></returns>
            public T GetCache<T>(string key) where T : class
            {
                if (string.IsNullOrWhiteSpace(key))
                    throw new ArgumentNullException(nameof(key));
                T v = null;
                _cache.TryGetValue<T>(key, out v);
                return v;
            }

            /// <summary>
                    /// 设置缓存
                    /// </summary>
                    /// <param name="key"></param>
                    /// <param name="value"></param>
            public void SetCache(string key, object value)
            {
                if (string.IsNullOrWhiteSpace(key))
                    throw new ArgumentNullException(nameof(key));
                if (value == null)
                    throw new ArgumentNullException(nameof(value));
                object v = null;
                if (_cache.TryGetValue(key, out v))
                    _cache.Remove(key);
                _cache.Set<object>(key, value);
            }

            /// <summary>
                    /// 设置缓存,绝对过期
                    /// </summary>
                    /// <param name="key"></param>
                    /// <param name="value"></param>
                    /// <param name="expirationMinute">间隔分钟</param>
                    /// MemoryCacheService.Default.SetCache("test", "RedisCache works!", 30);
            public void SetCache(string key, object value, double expirationMinute)
            {
                if (string.IsNullOrWhiteSpace(key))
                    throw new ArgumentNullException(nameof(key));
                if (value == null)
                    throw new ArgumentNullException(nameof(value));

                object v = null;
                if (_cache.TryGetValue(key, out v))
                    _cache.Remove(key);
                DateTime now = DateTime.Now;
                TimeSpan ts = now.AddMinutes(expirationMinute) - DateTime.Now;
                _cache.Set<object>(key, value, ts);
            }

            /// <summary>
                    /// 设置缓存,绝对过期
                    /// </summary>
                    /// <param name="key"></param>
                    /// <param name="value"></param>
                    /// <param name="expirationTime">DateTimeOffset 结束时间</param>
                    /// MemoryCacheService.Default.SetCache("test", "RedisCache works!", DateTimeOffset.Now.AddSeconds(30));
            public void SetCache(string key, object value, DateTimeOffset expirationTime)
            {
                if (string.IsNullOrWhiteSpace(key))
                    throw new ArgumentNullException(nameof(key));
                if (value == null)
                    throw new ArgumentNullException(nameof(value));

                object v = null;
                if (_cache.TryGetValue(key, out v))
                    _cache.Remove(key);

                _cache.Set<object>(key, value, expirationTime);
            }

            /// <summary>
                    /// 设置缓存,相对过期时间
                    /// </summary>
                    /// <param name="key"></param>
                    /// <param name="value"></param>
                    /// <param name="t"></param>
                    /// MemoryCacheService.Default.SetCache("test", "MemoryCache works!",TimeSpan.FromSeconds(30));
            public void SetSlidingCache(string key, object value, TimeSpan t)
            {
                if (string.IsNullOrWhiteSpace(key))
                    throw new ArgumentNullException(nameof(key));
                if (value == null)
                    throw new ArgumentNullException(nameof(value));

                object v = null;
                if (_cache.TryGetValue(key, out v))
                    _cache.Remove(key);

                _cache.Set(key, value, new MemoryCacheEntryOptions()
                {
                    SlidingExpiration = t
                });
            }

            /// <summary>
                    /// 移除缓存
                    /// </summary>
                    /// <param name="key"></param>
            public void RemoveCache(string key)
            {
                if (string.IsNullOrWhiteSpace(key))
                    throw new ArgumentNullException(nameof(key));

                _cache.Remove(key);
            }

            /// <summary>
                    /// 释放
                    /// </summary>
            public void Dispose()
            {
                if (_cache != null)
                    _cache.Dispose();
                GC.SuppressFinalize(this);
            }
        

    }
}
